package com.serviceprovider.business.module.order.services.dao.impl;

//~--- non-JDK imports --------------------------------------------------------

import com.serviceprovider.business.module.order.model.ConditionType;
import com.serviceprovider.business.module.order.model.OrderConditionField;
import com.serviceprovider.business.module.order.model.OrderFilter;
import com.serviceprovider.business.module.order.model.OrderFilterCondition;
import com.serviceprovider.business.module.order.services.dao.interfaces.IOrderFilterDao;
import com.serviceprovider.business.module.order.valueobjects.OrderFilterVO;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.stereotype.Repository;

//~--- JDK imports ------------------------------------------------------------

import java.sql.ResultSet;
import java.sql.SQLException;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Repository("orderFilterDao")
public class OrderFilterDaoImpl extends JdbcDaoSupport implements IOrderFilterDao {
    @Autowired
    public OrderFilterDaoImpl(@Qualifier("jdbcTemplate") JdbcTemplate jdbcTemplate) {
        setJdbcTemplate(jdbcTemplate);
    }

    @Override
    public List<OrderFilter> findAll() {
        String            sql    = "select * from order_filters";
        List<OrderFilter> result = getJdbcTemplate().query(sql, new OrderFilterMapper());

        return result;
    }

    @Override
    public OrderFilter getById(Integer id) {
        String sql = "select * from order_filters where id=?";

        return (OrderFilter) getJdbcTemplate().queryForObject(sql, new Object[] { id }, new OrderFilterMapper());
    }

    @Override
    public void createNew(OrderFilter entity) {
        SimpleJdbcInsert simpleJdbcInsert =
            new SimpleJdbcInsert(getJdbcTemplate()).withTableName("order_filters").usingGeneratedKeyColumns("id");
        Map<String, Object> parameters = new HashMap<String, Object>();

        parameters.put("name", entity.getName());
        parameters.put("active", entity.isActive());

        Number id = simpleJdbcInsert.executeAndReturnKey(parameters);

        entity.setId(id.intValue());
        updateConditionList(entity);
    }

    @Override
    public void update(OrderFilter entity) {
        String sql = "update order_filters set name=?, active=? where id=?";

        getJdbcTemplate().update(sql, new Object[] { entity.getName(), entity.isActive(), entity.getId() });
        sql = "delete from order_filter_conditions where order_filter_id=?";
        getJdbcTemplate().update(sql, new Object[] { entity.getId() });
        updateConditionList(entity);
    }

    @Override
    public void remove(OrderFilter entity) {
        removeById(entity.getId());
    }

    @Override
    public void removeById(Integer id) {
        String sql = "delete from order_filter_conditions where order_filter_id=?";

        getJdbcTemplate().update(sql, new Object[] { id });
        sql = "delete from order_filters where id=?";
        getJdbcTemplate().update(sql, new Object[] { id });
    }

    private void updateConditionList(OrderFilter orderFilter) {
        List<OrderFilterCondition> list = orderFilter.getFilterConditionList();
        String                     sql  = "insert into order_filter_conditions "
                     + "(order_filter_id,condition_field,condition_type,condition_value) " + "values(?,?,?,?)";

        for (OrderFilterCondition item : list) {
            getJdbcTemplate().update(sql, new Object[] { orderFilter.getId(), item.getOrderConditionField().toString(),
                    item.getConditionType().toString(), item.getConditionValue() });
        }
    }

    @Override
    public List<OrderFilter> findAllActive() {
        String            sql    = "select * from order_filters where active=1";
        List<OrderFilter> result = getJdbcTemplate().query(sql, new OrderFilterMapper());

        return result;
    }

    private class OrderFilterMapper implements RowMapper {
        @Override
        public Object mapRow(ResultSet resultSet, int i) throws SQLException {
            OrderFilter result = new OrderFilter();

            result.setId(resultSet.getInt("id"));
            result.setName(resultSet.getString("name"));
            result.setActive(resultSet.getBoolean("active"));
            result.setFilterConditionList(getConditionList(result.getId()));

            return result;
        }

        private List<OrderFilterCondition> getConditionList(Integer id) {
            String                     sql    = "select * from order_filter_conditions where order_filter_id=?";
            List<OrderFilterCondition> result = OrderFilterDaoImpl.this.getJdbcTemplate().query(sql,
                                                    new Object[] { id }, new RowMapper() {
                @Override
                public Object mapRow(ResultSet resultSet, int i) throws SQLException {
                    OrderFilterCondition result = new OrderFilterCondition();

                    result.setConditionType(ConditionType.valueOf(resultSet.getString("condition_type")));
                    result.setOrderConditionField(OrderConditionField.valueOf(resultSet.getString("condition_field")));
                    result.setConditionValue(resultSet.getString("condition_value"));

                    return result;
                }
            });

            return result;
        }
    }
}



